package org.qpcr.community.standalone.authorize;

import org.hswebframework.web.authorization.Authentication;
import org.hswebframework.web.authorization.Dimension;
import org.hswebframework.web.authorization.Permission;
import org.hswebframework.web.authorization.events.AuthorizationDecodeEvent;
import org.hswebframework.web.authorization.events.AuthorizationSuccessEvent;
import org.hswebframework.web.authorization.exception.AuthenticationException;
import org.hswebframework.web.system.authorization.api.service.reactive.ReactiveUserService;
import org.qpcr.community.auth.service.UserDetailService;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Lind
 * @since 1.0.0
 */
@Component
public class LoginEvent {
    private final UserDetailService detailService;
    private final ReactiveUserService userService;
    private static final String FIRST_LOGIN_STATUS = "40001";

    public LoginEvent(UserDetailService detailService, ReactiveUserService userService) {
        this.detailService = detailService;
        this.userService = userService;
    }

    @EventListener
    public void AuthorizationDecodeEvent(AuthorizationDecodeEvent event) {
        String username = event.getUsername();
        String password = event.getPassword();
        try{
            String platform = event.getParameter("platform").get().toString();//pc  app
            event.async(
                    userService.findByUsername(username)
                            .flatMap(userEntity -> {
                                //触发授权成功事件
                                if("pc".equals(platform)){
                                    if (userEntity ==null || userEntity.getType().equals("other")) {
                                        return Mono.error(new RuntimeException("用户不能登录管理端"));
                                    } else {
                                        return Mono.empty();
                                    }
                                }else{
                                    return Mono.empty();
                                }
                            })
            );
        }catch (Exception e){

        }
    }

    @EventListener
    public void handleLoginSuccess(AuthorizationSuccessEvent event) {
        Map<String, Object> result = event.getResult();
        Authentication authentication = event.getAuthentication();
        List<Dimension> dimensions = authentication.getDimensions();

        result.put("permissions", authentication.getPermissions());
        result.put("roles", dimensions);
        result.put("currentAuthority", authentication.getPermissions().stream().map(Permission::getId).collect(Collectors.toList()));

        event.async(
                detailService
                        .findUserDetail(event.getAuthentication().getUser().getId())
                        .flatMap(detail -> {
                            result.put("user", detail);
                            // 判断是否首次登录
                            boolean isFirstLogin = detail.getLastLoginTime() == null;

                            // 如果是首次登录，抛出认证异常
                            if (isFirstLogin) {
                                return Mono.error(new AuthenticationException(FIRST_LOGIN_STATUS, "首次登录需要修改密码"));
                            }
                            return Mono.just(detail);
                        })
        );
    }
}
